#ifndef COMMUNICATOR_H
#define COMMUNICATOR_H

class AbstractStorage;
class ScriptApplication;
class Settings;
class DataTreeHelper;
class QXmlStreamWriter;
#include "messenger.h"
#include <QStringList>
#include <QObject>

class Communicator : public QObject
{
    Q_OBJECT
public:    
    ~Communicator();

    static Communicator *instance();

    Q_INVOKABLE bool sendTableData(DataTreeHelper *dataTree, int servNo = 0);
    Q_INVOKABLE bool sendDoc(DataTreeHelper *dataTree, int servNo = 0);
    Q_INVOKABLE bool sendMessage(const QString& params, int servNo = 0);
    Q_INVOKABLE QString getRemoteInfo(const QString& params, int servNo = 0);
    Q_INVOKABLE bool getRemoteFile(const QString& name, int servNo = 0);
    Q_INVOKABLE bool getRemoteTable(const QString &tablesName, const QString &vars, int servNo = 0, const QString &dbName = QString());
    Q_INVOKABLE bool getRemoteDoc(const QString &docName, const QString &vars, const QString &deleteFilter = QString(), int servNo = 0, const QString &dbName = QString());    
    Q_INVOKABLE int serversCount();
    Q_INVOKABLE QStringList serversList();

private:
    Communicator();

    void writeXmlHead(QXmlStreamWriter *pXml, const QString &command,  const QStringList &tables = QStringList(), const QString &variables = QString());
    bool sendCommand(const QString &command, int servNo = 0, const QString &variables = QString(), const QStringList &tables = QStringList());
    void processMessage(const QString &command, Message *message);
    bool processGetFile(Message *message);
    bool processGetRemoteTable(Message *message, const QString &dbName = QString(), const QString &deleteFilter = QString());

    inline void reportError(const QString &errMsg);

private:
    static Communicator *m_instance;

    AbstractStorage *m_project;
    ScriptApplication *m_app;
    Settings *m_settings;
    Messenger m_messenger;
};

#endif // COMMUNICATOR_H
